package com.hunan.yllxy.util;


import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @Author: 刘华
 * @Date: 2024/2/21 0021 19:48
 * @Version 1.0
 */
public class DateUtils {
    public static String FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static String FORMAT2 = "yyyy/MM/dd HH:mm:ss";
    public static String FORMAT5 = "yyyyMMddHHmmss";
    public static String FORMAT6 = "yyyy-MM-dd HH:mm";
    public static String FORMAT8 = "yyyy-MM-dd HH";
    public static String FORMAT8_1 = "yyyy_MM_dd_HH";
    public static String FORMAT1 = "yyyy-MM-dd";
    public static String FORMAT3 = "yyyy/MM/dd";
    public static String FORMAT4 = "yyyyMMdd";
    public static String FORMAT7 = "yyyy-MM";
    public static String FORMAT13 = "yyyy";
    public static String FORMAT10 = "yyyy-MM-dd HH24";
    public static String FORMAT11 = "HH:mm";
    public static String FORMAT12 = "HH时";


    public static final int TWENTYFOUR = 24;


    public static Date stringToDate(String date) {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        SimpleDateFormat simpleDateFormat = null;
        Date s = null;
        try {
            simpleDateFormat = new SimpleDateFormat(FORMAT);
            s = simpleDateFormat.parse(date);
        } catch (Exception exception) {
            try {
                simpleDateFormat = new SimpleDateFormat(FORMAT2);
                s = simpleDateFormat.parse(date);
            } catch (Exception e) {

                try {
                    simpleDateFormat = new SimpleDateFormat(FORMAT6);
                    s = simpleDateFormat.parse(date);
                } catch (ParseException e2) {
                    try {
                        simpleDateFormat = new SimpleDateFormat(FORMAT8);
                        s = simpleDateFormat.parse(date);
                    } catch (ParseException e3) {
                        try {
                            simpleDateFormat = new SimpleDateFormat(FORMAT1);
                            s = simpleDateFormat.parse(date);
                        } catch (ParseException ex) {
                            try {
                                simpleDateFormat = new SimpleDateFormat(FORMAT3);
                                s = simpleDateFormat.parse(date);

                            } catch (ParseException e4) {
                                try {
                                    simpleDateFormat = new SimpleDateFormat(FORMAT7);
                                    s = simpleDateFormat.parse(date);

                                } catch (ParseException e5) {
                                    try {
                                        simpleDateFormat = new SimpleDateFormat(FORMAT4);
                                        s = simpleDateFormat.parse(date);
                                    } catch (ParseException e6) {
                                        try {
                                            simpleDateFormat = new SimpleDateFormat(FORMAT13);
                                            s = simpleDateFormat.parse(date);
                                        } catch (ParseException e7) {
                                            e7.printStackTrace();
                                            throw new RuntimeException("不符合时间格式");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return s;
    }

    public static Date stringToDate(String date, String format) {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        Date s = null;
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
            s = simpleDateFormat.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return s;
    }

    public static Date addDateHour(Date date, Integer hour) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        //把日期往后增加一天.整数往后推,负数往前移动
        calendar.add(GregorianCalendar.HOUR_OF_DAY, hour);
        //这个时间就是日期往后推一天的结果
        date = calendar.getTime();
        return date;
    }

    public static Date firstHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
// 设置为当月第一天
//        calendar.set(Calendar.DAY_OF_MONTH, 1);
// 将小时、分钟、秒钟、毫秒设为最小值
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date lastHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
// 设置为当月第一天
//        calendar.set(Calendar.DAY_OF_MONTH, 1);
// 将小时、分钟、秒钟、毫秒设为最小值
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }


    public static Date firstYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH,Calendar.JANUARY);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        // 将小时、分钟、秒钟、毫秒设为最大值
        return calendar.getTime();
    }

    public static Date lastYear(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
// 设置为当月第一天
//        calendar.set(Calendar.DAY_OF_MONTH, 1);
// 将小时、分钟、秒钟、毫秒设为最小值
        Integer maxMonth = getMaxMonth(date);
        calendar.set(Calendar.MONTH, Calendar.DECEMBER);
        calendar.set(Calendar.DAY_OF_MONTH, 31);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }
    public static Integer getMaxMonth(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        int actualMaximum = calender.getActualMaximum(Calendar.DATE);
        return actualMaximum;
    }
    public static Date firstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
// 设置为当月第一天
//        calendar.set(Calendar.DAY_OF_MONTH, 1);
// 将小时、分钟、秒钟、毫秒设为最小值
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date lastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
// 设置为当月第一天
//        calendar.set(Calendar.DAY_OF_MONTH, 1);
// 将小时、分钟、秒钟、毫秒设为最小值
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    public static Integer getMaxMonthDay(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        int actualMaximum = calender.getActualMaximum(Calendar.DATE);
        return actualMaximum;
    }

    public static Integer getMinMonth(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        int actualMinimum = calender.getActualMinimum(Calendar.DATE);
        return actualMinimum;
    }

    public static LocalDate getWeekOne(LocalDate now) {
        return now.with(DayOfWeek.MONDAY);
    }

    public static Date dateToDate(Date date, String format) {
        if (format == null) {
            format = FORMAT1;
        }
        String stringDate = getStringDate(date, format);
        return stringToDate(stringDate);
    }


    public static String getStringDate(Date date, String format) {
        if (format == null) {
            format = FORMAT1;
        }
        if (date == null) {
            return null;
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        String s = simpleDateFormat.format(date);
        return s;
    }

    public static LocalDateTime getLocalDateTimeString(String date) {
        DateTimeFormatter df = null;
        LocalDateTime data = null;
        try {
            df = DateTimeFormatter.ofPattern(FORMAT);
            data = LocalDateTime.parse(date, df);
        } catch (Exception e) {
            try {
                df = DateTimeFormatter.ofPattern(FORMAT2);
                data = LocalDateTime.parse(date, df);
            } catch (Exception exception) {
                exception.printStackTrace();
                throw new RuntimeException(exception.getMessage());
            }
        }
        return data;
    }

    public static Date localDateTimToDate(LocalDateTime localDateTime) {
        DateTimeFormatter df = null;
        Date date = null;

        try {
            // 假设你的系统默认时区是你要转换的时区
            ZoneId zoneId = ZoneId.systemDefault();
            // 转换为ZonedDateTime
            ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
            // 转换为Instant
            Instant instant = zonedDateTime.toInstant();
            // 转换为Date
            date = Date.from(instant);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return date;
    }

    public static LocalDate getLocalDateString(String date) {
        DateTimeFormatter df = null;
        LocalDate data = null;
        try {
            df = DateTimeFormatter.ofPattern(FORMAT1);
            data = LocalDate.parse(date, df);
        } catch (Exception e) {
            try {
                df = DateTimeFormatter.ofPattern(FORMAT3);
                data = LocalDate.parse(date, df);
            } catch (Exception e1) {
                try {
                    df = DateTimeFormatter.ofPattern(FORMAT4);
                    data = LocalDate.parse(date, df);
                } catch (Exception exception) {
                    exception.printStackTrace();
                    throw new RuntimeException(exception.getMessage());
                }
            }
        }
        return data;
    }

    public static boolean dateAddAndSubtract(Date stop, Date start) {
//日期相减得到相差的日期
        if (start == null) {
            start = new Date();
        }
        if (stop == null) {
            stop = new Date();
        }
        boolean b = stop.getTime() > start.getTime() ? true : false;
        return b;
    }

    public static String dateAddAndSubtractString(Date start, Date stop) {
        Double dateDouble = 0d;
        long l = start.getTime() - stop.getTime() > 0 ? start.getTime() - stop.getTime() :
                stop.getTime() - start.getTime();
        dateDouble = getDoubleTwo((double) l / 1000d / 60d / 60d);
        if (dateDouble >= TWENTYFOUR) {
            dateDouble = getDoubleTwo((double) l / 1000d / 60d / 60d / 24d);
            return dateDouble + "天";
        } else {
            return dateDouble + "小时";
        }
    }

    public static Integer hourDifference(Date start, Date stop) {
        Double dateDouble = 0d;
        long l = start.getTime() - stop.getTime() > 0 ? start.getTime() - stop.getTime() :
                stop.getTime() - start.getTime();
        dateDouble = getDoubleTwo((double) l / 1000d / 60d / 60d);
        return dateDouble.intValue();

    }

    public static Double getDoubleTwo(Double d) {
        DecimalFormat df = new DecimalFormat("#.##");
        String format = df.format(d);
        Double v = Double.parseDouble(format);
        return v;
    }

    public static Double getDoubleDecimals(Double d, Integer num) {
        String str = "1";
        for (Integer i = 0; i < num; i++) {
            str += "0";
        }
        Double i = Double.parseDouble(str);
        double v1 = Math.round(d * i) / i;
        return v1;
    }


    public static Integer getYear(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
//        int year = calender.get(Calendar.YEAR) + 1900;
        int year = calender.get(Calendar.YEAR);
        return year;
    }

    public static Integer getMonth(Date date) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(date);
        int month = calender.get(Calendar.MONTH) + 1;
        return month;
    }
    public static Integer getDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        int i = calendar.get(Calendar.DATE);
        return i;
    }

    public static Integer getHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int value = calendar.get(Calendar.HOUR_OF_DAY);
        return value;
    }

    public static Integer getYear() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        return year;
    }

    public static Integer getMonth() {
        Calendar calendar = Calendar.getInstance();
        int value = calendar.get(Calendar.MONTH) + 1;
        return value;
    }





    public static Date addDateDay(Date date, Integer day) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        //把日期往后增加一天.整数往后推,负数往前移动
        calendar.add(GregorianCalendar.DATE, day);
        //这个时间就是日期往后推一天的结果
        date = calendar.getTime();
        return date;
    }

    /**
     * 获取当月最后一刻
     *
     * @param date
     * @return
     */
    public static Date lastDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
//        calendar.add(Calendar.MONTH, 1);
//        calendar.add(Calendar.DATE, -1);
// 将小时、分钟、秒钟、毫秒设为最大值
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.roll(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }

    /**
     * 获取当月第一天
     *
     * @param date
     * @return
     */
    public static Date firstDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
// 设置为当月第一天
        calendar.set(Calendar.DAY_OF_MONTH, 1);
// 将小时、分钟、秒钟、毫秒设为最小值
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date addDateMonth(Date date, Integer month) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        //这个时间就是日期往后推一天的结果
        date = calendar.getTime();
        return date;
    }

    public static Date addDateYear(Date date, Integer day) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        //把日期往后增加一天.整数往后推,负数往前移动
        calendar.add(GregorianCalendar.YEAR, day);
        //这个时间就是日期往后推一天的结果
        date = calendar.getTime();
        return date;
    }

    public static Date addDateMinutDate(Date date, Integer hour) {
        if (date == null) {
            date = new Date();
        }
        if (hour == null) {
            hour = 4;
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //输入的日期
        System.out.println("front:" + format.format(date));
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 24小时制
        cal.add(Calendar.HOUR, hour);
        date = cal.getTime();
        return date;

    }

    public static String stringToDate() {
        Date dt = Date.from(Instant.now());
        String stringDate = getStringDate(dt, FORMAT);
        return stringDate;
    }

    public static Date getNowDate() {
        Date date = stringToDate("2024-03-18 22:44:01");
//        Date date = new Date();
        return date;
    }

    public static Date newDateFirst(Integer year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month-1);
// 设置为当月第一天
        calendar.set(Calendar.DAY_OF_MONTH, 1);
// 将小时、分钟、秒钟、毫秒设为最小值
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date newDateLast(Integer year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month-1);
// 将小时、分钟、秒钟、毫秒设为最大值
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.roll(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTime();
    }

    public static Date generateRandomDate(Date startDate, Date endDate) {
        // 校验时间范围
        if (startDate.after(endDate)) {
            throw new IllegalArgumentException("起始时间不能晚于结束时间");
        }

        // 转换为毫秒值
        long startMillis = startDate.getTime();
        long endMillis = endDate.getTime();

        // 生成随机毫秒值（包含 start 和 end）
        long randomMillis = ThreadLocalRandom.current()
                .nextLong(startMillis, endMillis + 1);

        return new Date(randomMillis);
    }
}
